using System.Collections.Generic;
using GameFramework.UI;
using UnityGameFramework.Runtime;
using GameFramework.Event;
using System;
using GameFramework.Resource;
using UnityEngine;
using XLua;
using Object = UnityEngine.Object;

[LuaCallCSharp]
public static class LuaUIFramework
{
    public static void SetLuaUILogicCallback(Action<LuaFormLogic> callback)
    {
        LuaFormLogic.__CallbackForLua = callback;
    }
    
    public static bool HasUIGroup(string uiGroupName)
    {
        return EntityInst.UI.HasUIGroup(uiGroupName);
    }
    
    public static IUIGroup GetUIGroup(string uiGroupName)
    {
        return EntityInst.UI.GetUIGroup(uiGroupName);
    }
    
    public static IUIGroup[] GetAllUIGroups()
    {
        return EntityInst.UI.GetAllUIGroups();
    }
    
    public static void GetAllUIGroups(List<IUIGroup> results)
    {
        EntityInst.UI.GetAllUIGroups(results);
    }
    
    public static bool AddUIGroup(string uiGroupName)
    {
        return AddUIGroup(uiGroupName, 0);
    }
    
    public static bool AddUIGroup(string uiGroupName, int depth)
    {
        return EntityInst.UI.AddUIGroup(uiGroupName, depth);
    }
    
    public static bool HasUIForm(int serialId)
    {
        return EntityInst.UI.HasUIForm(serialId);
    }
    
    public static bool HasUIForm(string uiFormAssetName)
    {
        return EntityInst.UI.HasUIForm(uiFormAssetName);
    }
    
    public static UIForm GetUIForm(int serialId)
    {
        return EntityInst.UI.GetUIForm(serialId);
    }
    
    public static UIForm GetUIForm(string uiFormAssetName)
    {
        return EntityInst.UI.GetUIForm(uiFormAssetName);
    }
    
    public static UIForm[] GetUIForms(string uiFormAssetName)
    {
        return EntityInst.UI.GetUIForms(uiFormAssetName);
    }
    
    public static void GetUIForms(string uiFormAssetName, List<UIForm> results)
    {
        EntityInst.UI.GetUIForms(uiFormAssetName, results);
    }
    
    public static UIForm[] GetAllLoadedUIForms()
    {
        return EntityInst.UI.GetAllLoadedUIForms();
    }
    
    public static void GetAllLoadedUIForms(List<UIForm> results)
    {
        EntityInst.UI.GetAllLoadedUIForms(results);
    }
    
    public static int[] GetAllLoadingUIFormSerialIds()
    {
        return EntityInst.UI.GetAllLoadingUIFormSerialIds();
    }
    
    public static void GetAllLoadingUIFormSerialIds(List<int> results)
    {
        EntityInst.UI.GetAllLoadingUIFormSerialIds(results);
    }
    
    public static bool IsLoadingUIForm(int serialId)
    {
        return EntityInst.UI.IsLoadingUIForm(serialId);
    }
    
    public static bool IsLoadingUIForm(string uiFormAssetName)
    {
        return EntityInst.UI.IsLoadingUIForm(uiFormAssetName);
    }
    
    public static bool IsValidUIForm(UIForm uiForm)
    {
        return EntityInst.UI.IsValidUIForm(uiForm);
    }
    
    public static int OpenUIForm(string uiFormAssetName, string uiGroupName)
    {
        return EntityInst.UI.OpenUIForm(uiFormAssetName, uiGroupName);
    }
    
    public static int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority)
    {
        return EntityInst.UI.OpenUIForm(uiFormAssetName, uiGroupName, priority);
    }
    
    public static int OpenUIForm(string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm)
    {
        return EntityInst.UI.OpenUIForm(uiFormAssetName, uiGroupName, pauseCoveredUIForm);
    }
    
    public static int OpenUIForm(string uiFormAssetName, string uiGroupName, object userData)
    {
        return EntityInst.UI.OpenUIForm(uiFormAssetName, uiGroupName, userData);
    }
    
    public static int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm)
    {
        return EntityInst.UI.OpenUIForm(uiFormAssetName, uiGroupName, priority, pauseCoveredUIForm);
    }

    public static int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, object userData)
    {
        return EntityInst.UI.OpenUIForm(uiFormAssetName, uiGroupName, priority, userData);
    }
    
    public static int OpenUIForm(string uiFormAssetName, string uiGroupName, bool pauseCoveredUIForm, object userData)
    {
        return EntityInst.UI.OpenUIForm(uiFormAssetName, uiGroupName, pauseCoveredUIForm, userData);
    }
    
    public static int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm, object userData)
    {
        return EntityInst.UI.OpenUIForm(uiFormAssetName, uiGroupName, priority, pauseCoveredUIForm, userData);
    }
    
    public static void CloseUIForm(int serialId)
    {
        EntityInst.UI.CloseUIForm(serialId);
    }
    
    public static void CloseUIForm(int serialId, object userData)
    {
        EntityInst.UI.CloseUIForm(serialId, userData);
    }
    
    public static void CloseUIForm(UIForm uiForm)
    {
        EntityInst.UI.CloseUIForm(uiForm);
    }
    
    public static void CloseUIForm(UIForm uiForm, object userData)
    {
        EntityInst.UI.CloseUIForm(uiForm, userData);
    }
    
    public static void CloseAllLoadedUIForms()
    {
        EntityInst.UI.CloseAllLoadedUIForms();
    }
    
    public static void CloseAllLoadedUIForms(object userData)
    {
        EntityInst.UI.CloseAllLoadedUIForms(userData);
    }
    
    public static void CloseAllLoadingUIForms()
    {
        EntityInst.UI.CloseAllLoadingUIForms();
    }
    
    public static void RefocusUIForm(UIForm uiForm)
    {
        EntityInst.UI.RefocusUIForm(uiForm);
    }
    
    public static void RefocusUIForm(UIForm uiForm, object userData)
    {
        EntityInst.UI.RefocusUIForm(uiForm, userData);
    }
    
    public static void SetUIFormInstanceLocked(UIForm uiForm, bool locked)
    {
        EntityInst.UI.SetUIFormInstanceLocked(uiForm, locked);
    }
    
    public static void SetUIFormInstancePriority(UIForm uiForm, int priority)
    {
        EntityInst.UI.SetUIFormInstancePriority(uiForm, priority);
    }
}

[LuaCallCSharp]
public static class LuaEventFramework
{
    public static int EventHandlerCount
    {
        get { return EntityInst.Event.EventHandlerCount; }
    }
    
    public static int EventCount
    {
        get { return EntityInst.Event.EventCount; }
    }
    
    public static int Count(int id)
    {
        return EntityInst.Event.Count(id);
    }
    
    public static bool Check(int id, EventHandler<GameEventArgs> handler)
    {
        return EntityInst.Event.Check(id, handler);
    }
    
    public static void Subscribe(int id, EventHandler<GameEventArgs> handler)
    {
        EntityInst.Event.Subscribe(id, handler);
    }
    
    public static void Unsubscribe(int id, EventHandler<GameEventArgs> handler)
    {
        EntityInst.Event.Unsubscribe(id, handler);
    }
    
    public static void SetDefaultHandler(EventHandler<GameEventArgs> handler)
    {
        EntityInst.Event.SetDefaultHandler(handler);
    }
    
    public static void Fire(object sender, GameEventArgs e)
    {
        EntityInst.Event.Fire(sender, e);
    }
    
    public static void FireNow(object sender, GameEventArgs e)
    {
        EntityInst.Event.FireNow(sender, e);
    }
}

[LuaCallCSharp]
public static class LuaConfigFramework
{
    public static bool SetBool(string key, bool value)
    {
        if (EntityInst.Config.HasConfig(key))
            EntityInst.Config.RemoveConfig(key);
        return EntityInst.Config.AddConfig(key, value,0,0,null);
    }

    public static bool SetFloat(string key, float value)
    {
        if (EntityInst.Config.HasConfig(key))
            EntityInst.Config.RemoveConfig(key);
        return EntityInst.Config.AddConfig(key, false,0,value,null);
    }

    public static bool SetString(string key, string value)
    {
        if (EntityInst.Config.HasConfig(key))
            EntityInst.Config.RemoveConfig(key);
        return EntityInst.Config.AddConfig(key, false,0,0,value);
    }

    public static bool GetBool(string key)
    {
        return EntityInst.Config.GetBool(key);
    }

    public static float GetFloat(string key)
    {
        return EntityInst.Config.GetFloat(key);
    }

    public static string GetString(string key)
    {
        return EntityInst.Config.GetString(key);
    }

    public static bool HasConfig(string key)
    {
        return EntityInst.Config.HasConfig(key);
    }
}

[LuaCallCSharp]
public static class LuaResourceFramework
{
    private static LoadAssetCallbacks _callback = new LoadAssetCallbacks(OnLoadAssetSuccessCallback,OnLoadAssetFailureCallback);
    private static Dictionary<int, Action<object>> _resCallbackMap = new Dictionary<int, Action<object>>();
    public static void LoadAsset(string assetName,Action<object> callback)
    {
        var tcode = callback.GetHashCode();
        var hash = new KeyValuePair<string, int>(assetName, tcode).GetHashCode();
        if (!_resCallbackMap.TryGetValue(hash, out var x))
        {
            _resCallbackMap.Add(hash,callback);
        }
        EntityInst.Resource.LoadAsset(assetName, _callback,callback.GetHashCode());
    }

    private static void OnLoadAssetSuccessCallback(string assetName, object asset, float duration, object userData)
    {
        if (_resCallbackMap.TryGetValue(new KeyValuePair<string, int>(assetName, (int) userData).GetHashCode(),
                out var x))
        {
            x(asset);
        }
    }

    private static void OnLoadAssetFailureCallback(string assetName, LoadResourceStatus status, string errorMessage, object userData)
    {
        throw new Exception($"LoadAsset {assetName} Failure ,error message = {errorMessage}");
    }
}

    [LuaCallCSharp]
public static class LuaProcedureUtility
{
    public static void ChangeState(string procedureName,string userData = null)
    {
        GameBaseProcedure.ChangeState(procedureName,userData);
    }
}